(function($){
var Upload = function (element, options) {
	   this.options = $.extend({
	       url: '',
	       rnd: Math.random(),
	       updateInterval: 500,
	       parseResponse: true,
	   }, options);
	   //this.$form, $fileInput, $iframe;
	   this.el = $(element);
    this._generateHtml();
		  this._listen();
	};

Upload.prototype = {
	   _generateHtml: function() {
	       //var $form, $fileInput, $iframe;
	       this.$form = $('<form method="post" enctype="multipart/form-data" encoding="multipart/form-data"></form>');
	       this.$fileInput = $('<input id="{%}" type="file" name="file" style="opacity: 0;position: absolute"/>'.format([ "inputUpl" + this.options.rnd ]));
        this.$iframe = $('<iframe name="{%}" src="javascript:false;"></iframe>'.format([ "frameUpl" + this.options.rnd ]));

        //this.$fileInput.width(this.el.outerWidth());
        this.$fileInput.height(this.el.outerHeight());
        var wrapper = $('<div style="position: relative; display: inline-block"></div>');
        //this.el.wrap(wrapper);
        //this.el.before(this.$fileInput);
	    //   this.$fileInput.css('margin-top', '-120px');
        this.$fileInput.appendTo(this.el);
        this.$iframe.appendTo(this.$form);//.hide();
 
        this.$form.prop('target', this.$iframe.prop('name'))
            .prop('action', this.options.url);
	           //.hide();
	       
        this.$form.wrap('<div>w4u4u</div>').parent().appendTo('#bdy');
	   },

	   initiate: function () {
	       //this.$fileInput.focus();
        //this.$fileInput.click();
    },
	   
	   _listen: function () {
	       //this.$fileInput.bind('click', function () {
	       //    alert('weg');
	       //    return false;
	       //});
	       this.$fileInput.change($.proxy(this._onselect, this));
		  },
		
		  _onselect: function(e) {
		      this.$form.submit();
		      //this.file = e.currentTarget.files[0];
			     //if (this.options.onSelect) {
				    //    this.options.onSelect.call(this);
				    //    return;
			     //}
			     //this.sendFile();
		  },
		
		  sendFile: function(data) {
			     if (!this.file) return;
			     var fd = new FormData();
			     fd.append(this.options.name, this.file);
		      if (data) {
				        for (var i in data) fd.append(i, data[i]);
			     }
			
			     this.start = (new Date()).getTime();
			
			     var xhr = new XMLHttpRequest();
			     xhr.upload.addEventListener("progress", $.proxy(this.update, this), false);
			     xhr.addEventListener("load", $.proxy(this.complete, this), false);
			     xhr.addEventListener("error", $.proxy(this.failed, this), false);
			     xhr.addEventListener("abort", $.proxy(this.cancelled, this), false);
			     xhr.open("POST", this.options.url);
			     xhr.send(fd);
			     this.xhr = xhr;

		      this.progress = {
		          lastBytes: 0,
		          total: this.file.size,
		          loaded: 0,
		          speed: 0
		      };

			     if (this.options.onUpdate) {
				        this.intervalUpdate = $.proxy(this.options.onUpdate, this);
				        this.timer = setInterval(this.intervalUpdate, this.options.updateInterval);
			     }
		  },
		
  		getPercentage: function() {
			     return Math.round(this.progress.loaded * 100 / this.progress.total);
		  },
		
		  getThroughput: function() {
			     return this.progress.throughput;
		  },

		  getSpeed: function() {
			     return this.progress.speed;
		  },

		  cancel: function() {
			     this.xhr.abort();
		  },

		  inProgress: function() {
			     return !!this.xhr;
		  },
		
		  update: function(e) {
			     if (!e.lengthComputable) return;
			     this.progress.total = e.total;
			     this.progress.loaded = e.loaded;
			
			     this.progress.throughput = Math.round(this.progress.loaded - this.progress.lastBytes);
			     this.progress.lastBytes = this.progress.loaded;
			
			     var elapsed = (new Date()).getTime() - this.start;
			     this.progress.speed = Math.round(1000 * this.progress.loaded / elapsed);
		  },
		
 		 complete: function(e) {
			     clearInterval(this.timer);
			     this.progress.loaded = this.progress.total;
			     this.intervalUpdate();
			     if (this.options.onComplete) {
				        var data = this.options.parseResponse ? jQuery.parseJSON(this.xhr.responseText) : undefined;
				        this.options.onComplete.call(this, data);
			     }
			     this.xhr = null;
		  },
		
		  failed: function(e) {
			     clearInterval(this.timer);
			     if (this.options.onError) {
				        this.options.onError.call(this, this.xhr);
			     }
			     this.xhr = null;
		  },
		
		  cancelled: function(e) {
			     clearInterval(this.timer);
			     if (this.options.onCancel) {
				        this.options.onCancel.call(this);
			     }
			     this.xhr = null;
		  }
};

$.fn.Upload = function (option, arg) {
    var $this = $(this),
     data = $this.data('Upload'),
     options = typeof option == 'object' && option;
    if (!data) $this.data('Upload', (data = new Upload(this, options)));
    if (typeof option == 'string') {
        return data[option](arg);
    }
    return data;
};

})(window.jQuery);